<?php

namespace app\admin\controller\autokeyword;

use app\common\controller\Backend;
use think\Db;
use think\Exception;
use think\exception\PDOException;
use think\exception\ValidateException;

/**
 * 前台生效规则管理
 * @icon fa fa-circle-o
 */
class Index extends Backend
{

    /**
     * AutokeywordTable模型对象
     * @var \app\admin\model\AutokeywordIndex
     */
    protected $model = null;

    /**
     * 控制器名称列表
     * @var array
     */
    protected $controllerList = [];

    /**
     * 控制器方法列表
     * @var array
     */
    protected $actionList = [];

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\AutokeywordIndex;
        $this->view->assign("markList", $this->model->getMarkList());
    }

    public function import()
    {
        parent::import();
    }

    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */

    /**
     * 添加
     */
    public function add()
    {

        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                $params = $this->preExcludeFields($params);

                if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
                    $params[$this->dataLimitField] = $this->auth->id;
                }
                $result = false;
                Db::startTrans();
                try {
                    //是否采用模型验证
                    if ($this->modelValidate) {
                        $name     = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
                        $this->model->validateFailException(true)->validate($validate);
                    }

                    $params['field'] = trim(implode(',', $params['field']), ',');

                    $result = $this->model->allowField(true)->save($params);
                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were inserted'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }

        $controllerList = $this->getControllerList();
        $actionList     = [];
        $module         = 'index';

        if (count($controllerList) > 0) {
            $list = $this->controllerList;
            reset($controllerList);
            $module     = key($controllerList);
            $className  = array_shift($list[$module]);
            $actionList = $this->getControllerAction($className);
        }

        $this->view->assign('module', $module);
        $this->view->assign('controllerList', $controllerList);
        $this->view->assign('actionList', $actionList);
        $this->view->assign('fieldList', [
            'title',
            'content',
            'bio',
        ]);

        return $this->view->fetch();
    }

    /**
     * 获取控制器列表
     * @return array
     */
    private function getControllerList()
    {
        $this->getClassName('index');
        $this->getClassName('api');

        return $this->controllerList;
    }

    /**
     * 获取控制器类名及对应命名空间
     *
     * @param string $moudle
     * @param string $dirs
     *
     * @return array|bool
     */
    private function getClassName(string $moudle = 'index', string $dirs = '')
    {
        // 控制器路径
        $rootIndexPath = ROOT_PATH . 'application' . DIRECTORY_SEPARATOR . $moudle . DIRECTORY_SEPARATOR . 'controller' . $dirs . DIRECTORY_SEPARATOR;

        $nameSpaceDS = str_replace("/", "\\", $dirs);
        $nameSpace   = 'app\\' . $moudle . '\controller' . "{$nameSpaceDS}" . '\\';

        try {
            // 读取目录内容
            $dir = scandir($rootIndexPath);
        } catch (Exception $e) {
            return false;
        }
        // 遍历查找
        foreach ($dir as $value) {
            if ($value == '.' || $value == '..') {
                continue;
            }

            if (is_dir($rootIndexPath . $value)) {
                $dirList = $this->getClassName($moudle, $dirs . DIRECTORY_SEPARATOR . $value);

                if (!$dirList) {
                    continue;
                }

                $this->controllerList = array_merge($this->controllerList, $dirList);
            };

            $suffix = explode('.', $value);

            if (!isset($suffix[1]) || $suffix[1] !== 'php') {
                continue;
            };

            // 判断是否是文件
            if (is_file($rootIndexPath . $value)) {
                if (!empty($dirs)) {
                    $suffix[0] = $dirs . DIRECTORY_SEPARATOR . $suffix[0];
                }

                $this->controllerList[$moudle][$suffix[0]] = $nameSpace . $suffix[0];
            };

        }

        return $this->controllerList;
    }

    /**
     * 获取对应控制的方法
     *
     * @param string $tableName
     *
     * @return bool|\ReflectionMethod[]
     */
    public function getControllerAction(string $className = '')
    {
        if (empty($className) && $this->request->isAjax()) {
            $controller = $this->request->post('controller');
            $module     = $this->request->post('module');

            $className = "app\\{$module}\controller\\{$controller}";
        }

        try {
            $rc = new \ReflectionClass($className);

            $actionAry = $rc->getMethods(\ReflectionMethod::IS_PUBLIC);

            if (!is_array($actionAry)) {
                return false;
            }

            $action = array_filter($actionAry, function ($arr) {
                foreach ($arr as $value) {
                    if ($value == "_initialize" || $value == "__construct") {
                        return false;
                    }

                    return true;
                }
            });

        } catch (\ReflectionException $e) {
            if ($e->getCode() === -1) {
                return $this->error('该控制器类不存在');
            }
        }

        return $action;
    }

    /**
     * 编辑
     */
    public function edit($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }

        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            if (!in_array($row[$this->dataLimitField], $adminIds)) {
                $this->error(__('You have no permission'));
            }
        }

        $controllerList = $this->getControllerList();
        $actionList     = $this->getControllerAction($controllerList[$row['module']][$row['controller']]);

        $this->view->assign('controllerList', $controllerList);
        $this->view->assign('actionList', $actionList);
        $this->view->assign('module', $row['module']);

        $row['field'] = explode(',', $row['field']);

        $fieldList = [
            'title',
            'content',
            'bio',
        ];

        $fieldList = array_unique(array_merge($fieldList, $row['field']));

        $this->view->assign('fieldList', $fieldList);

        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                $params = $this->preExcludeFields($params);
                $result = false;
                Db::startTrans();
                try {
                    //是否采用模型验证
                    if ($this->modelValidate) {
                        $name     = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                        $row->validateFailException(true)->validate($validate);
                    }

                    $params['field'] = trim(implode(',', $params['field']), ',');

                    $result = $row->allowField(true)->save($params);
                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were updated'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }

        $this->view->assign("row", $row);

        return $this->view->fetch();
    }

}